package test.zookeeper;  

import java.io.IOException;
import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;

/**  
 * @类名 ZkServerImpl.java  
 * @描述: 
 *     TODO
 * @作者 梅光弦  
 * @创建时间 2012-12-4 下午02:53:47  
 * @版本 v1.0  
 */
public class ZkServerImpl implements ZkServer, Watcher{

	private ZooKeeper zk=null;
	
	public void appendPresistentNode(String path, String data)
			throws KeeperException, InterruptedException {
		if(zk!=null){
			//创建一个节点root，数据是mydata,不进行ACL权限控制，节点为永久性的(即客户端shutdown了也不会消失)
			/**
			 * 创建一个给定的目录节点 path, 并给它设置数据，
			 * CreateMode 标识有四种形式的目录节点,分别是
			 * PERSISTENT：持久化目录节点，这个目录节点存储的数据不会丢失；
			 * PERSISTENT_SEQUENTIAL：顺序自动编号的目录节点，这种目录节点会根据当前已近存在的节点数自动加 1，然后返回给客户端已经成功创建的目录节点名；
			 * EPHEMERAL：临时目录节点，一旦创建这个节点的客户端与服务器端口也就是 session 超时，这种节点会被自动删除；
			 * EPHEMERAL_SEQUENTIAL：临时自动编号节点
			 */			
			zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);		
		}
	}

	public void appendTempNode(String path, String data)
			throws KeeperException, InterruptedException {
		if(zk!=null){
			//创建一个节点root，数据是mydata,不进行ACL权限控制，节点为永久性的(即客户端shutdown了也不会消失)
			/**
			 * 创建一个给定的目录节点 path, 并给它设置数据，
			 * CreateMode 标识有四种形式的目录节点,分别是
			 * PERSISTENT：持久化目录节点，这个目录节点存储的数据不会丢失；
			 * PERSISTENT_SEQUENTIAL：顺序自动编号的目录节点，这种目录节点会根据当前已近存在的节点数自动加 1，然后返回给客户端已经成功创建的目录节点名；
			 * EPHEMERAL：临时目录节点，一旦创建这个节点的客户端与服务器端口也就是 session 超时，这种节点会被自动删除；
			 * EPHEMERAL_SEQUENTIAL：临时自动编号节点
			 */	
			
			zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		}		
	}

	public void changeData(String path, String data) throws KeeperException,
			InterruptedException {
		if(zk!=null){
			//修改节点下的数据，第三个参数为版本，如果是-1，那会无视被修改的数据版本，直接改掉
			zk.setData(path, data.getBytes(), -1);
		}
	}

	public void delNode(String path) throws KeeperException,
			InterruptedException {
		if (zk != null) {  
            zk.delete(path, -1);  
        } 
	}

	public void destroy() throws InterruptedException {
		if(zk!=null){
			zk.close();
		}
	}

	public boolean exist(String path) throws KeeperException,
			InterruptedException {
		if(zk!=null){
			return zk.exists(path, true)!=null;
		}
        return false;
	}

	public List<String> getChilds(String path) throws KeeperException,
			InterruptedException {
		if(zk!=null){
			return zk.getChildren(path, true);
		}
		return null;
	}

	public String getData(String path) throws KeeperException,
			InterruptedException {
		if(zk!=null){
			byte[] b=zk.getData(path, true, null);
			return new String(b);
		}
        return null;
	}

	public void init(String address) throws IOException {
		zk=new ZooKeeper(address, 50000, this);
	}

	public void process(WatchedEvent event) {
		if(event.getType()==EventType.NodeDataChanged){ //节点数据发生变化触发一下事件
			if(event.getPath()!=null){
				try{
					System.out.println("---------------------------------------------------");
					System.out.println("监控到["+event.getPath()+"]发生变化，value="+this.getData(event.getPath()));
					System.out.println("---------------------------------------------------");
				} catch (KeeperException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} 
				
			}
		}
	}

}
 